package org.wang.generalcode.modules.sys.service.impl;

import cn.dev33.satoken.stp.StpUtil;
import cn.hutool.captcha.generator.CodeGenerator;
import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.convert.Convert;
import cn.hutool.core.lang.Assert;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import jakarta.annotation.Resource;
import lombok.RequiredArgsConstructor;
import org.springframework.data.redis.core.RedisTemplate;
import org.wang.generalcode.modules.sys.constant.CacheConstants;
import org.wang.generalcode.modules.sys.constant.SystemConstants;
import org.wang.generalcode.modules.sys.converter.UserConverter;
import org.wang.generalcode.modules.sys.excel.UserExportDTO;
import org.wang.generalcode.modules.sys.pojo.params.UserParams;
import org.wang.generalcode.modules.sys.pojo.entity.User;
import org.wang.generalcode.modules.sys.mapper.RoleMenuMapper;
import org.wang.generalcode.modules.sys.mapper.UserRoleMapper;
import org.wang.generalcode.modules.sys.pojo.params.UserPageParams;
import org.wang.generalcode.modules.sys.pojo.vo.UserPageVO;
import org.wang.generalcode.modules.sys.service.IUserRoleService;
import org.wang.generalcode.modules.sys.pojo.vo.UserVO;
import org.wang.generalcode.modules.sys.mapper.UserMapper;
import org.wang.generalcode.modules.sys.service.IUserService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.springframework.stereotype.Service;
import com.baomidou.mybatisplus.core.metadata.IPage;
import org.wang.generalcode.support.result.Result;
import org.wang.generalcode.support.result.ResultCode;
import org.wang.generalcode.support.sm4.SM4Utils;

import java.util.List;
import java.util.Set;

/**
 * 用户信息表 服务实现类
 *
 * @author wz
 * @since 2024-08-08
 */
@Service
@RequiredArgsConstructor
public class UserServiceImpl extends ServiceImpl<UserMapper, User> implements IUserService {

	@Resource
	private UserRoleMapper userRoleMapper;

	@Resource
	private IUserRoleService userRoleService;

	@Resource
	private RoleMenuMapper roleMenuMapper;

	@Resource
	private  CodeGenerator codeGenerator;

	@Resource
	private final UserConverter userConverter;

	private final RedisTemplate<String, Object> redisTemplate;

	@Override
	public IPage<UserPageVO> selectUserPage(IPage<UserPageVO> page, UserPageParams queryParams) {
		return page.setRecords(baseMapper.selectUserPage(page, queryParams));
	}

	@Override
	public UserVO getCurrentUserInfo() {

		Integer userId = Convert.toInt(StpUtil.getLoginId());

		// 获取登录用户基础信息
		User user = this.getOne(new LambdaQueryWrapper<User>()
				.eq(User::getId, userId)
				.select(
						User::getId,
						User::getUsername,
						User::getNickname,
						User::getAvatar
				)
		);
		// entity->VO
		UserVO userInfoVO = BeanUtil.copyProperties(user, UserVO.class);
		userInfoVO.setUserId(userId);

		// 用户角色集合
		Set<String> roles = userRoleMapper.getRoleCode(userId);
		userInfoVO.setRoles(roles);

		// 用户权限集合
		if (CollectionUtil.isNotEmpty(roles)) {
			Set<String> perms = roleMenuMapper.getRolePerms(roles);
			userInfoVO.setPerms(perms);
		}
		return userInfoVO;
	}

	@Override
	public Result validateCaptcha(String captchaKey, String captchaCode) {
		// 获取缓存中的验证码
		Object cacheVerifyCodeObj = redisTemplate.opsForValue().get(CacheConstants.CAPTCHA_CODE_PREFIX + captchaKey);

		if (cacheVerifyCodeObj == null) {
			return Result.failed(ResultCode.VERIFY_CODE_TIMEOUT, "验证码已过期");
		}

		String cacheVerifyCode = cacheVerifyCodeObj.toString();

		if (StrUtil.isEmptyIfStr(cacheVerifyCode)) {
			return Result.failed(ResultCode.VERIFY_CODE_TIMEOUT, "验证码已过期");
		}

		if (codeGenerator.verify(cacheVerifyCode, captchaCode)) {
			return Result.success("验证码正确");
		} else {
			return Result.failed(ResultCode.VERIFY_CODE_ERROR,"验证码不正确");
		}
	}

	@Override
	public boolean saveUser(UserParams userParams) {
		String username = userParams.getUsername();

		long count = this.count(new LambdaQueryWrapper<User>().eq(User::getUsername, username));
		Assert.isTrue(count == 0, "用户名已存在");

		// 实体转换 form->entity
		User entity = userConverter.toEntity(userParams);

		// 设置默认加密密码
		String defaultEncryptPwd = SystemConstants.DEFAULT_PASSWORD;
		entity.setPassword(SM4Utils.encryptStr(defaultEncryptPwd));

		// 新增用户
		boolean result = this.save(entity);

		if (result) {
			// 保存用户角色
			userRoleService.saveUserRoles(entity.getId(), userParams.getRoleIds());
		}
		return result;
	}

	@Override
	public List<UserExportDTO> listExportUsers(UserPageParams queryParams) {
		return baseMapper.listExportUsers(queryParams);
	}

	@Override
	public boolean updateUser(UserParams userParams) {

		// form -> entity
		User entity = userConverter.toEntity(userParams);

		// 修改用户
		boolean result = this.updateById(entity);

		if (result) {
			// 保存用户角色
			userRoleService.saveUserRoles(entity.getId(), userParams.getRoleIds());
		}
		return result;
	}

}
